package com.awesome.common.util.permissionutil;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.PowerManager;
import android.provider.Settings;

import com.awesome.common.util.activityresultutil.ActivityResultUtil;
import com.awesome.common.util.activityresultutil.OnActivityResultCallBack;
import com.awesome.common.util.device.AppUtil;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import androidx.core.content.PermissionChecker;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;

/**
 * Description:Android Api 23 以上的系统申请权限的工具类
 * Created by 禽兽先生
 * Created on 2018/4/18
 */
public class PermissionUtil {
    /**
     * Author: JFangZ
     * Email: janezhang1901@163.com
     * Date:2020/12/16 10:26
     * Description:申请权限，可同时申请多个
     *
     * @param fragmentManager
     * @param callBack        结果回调
     * @param permissions     需要申请的所有权限
     */
    private static void request(FragmentManager fragmentManager, RequestPermissionFragment.CallBack callBack, String... permissions) {
        if (permissions == null || permissions.length == 0) {
            return;
        }
        RequestPermissionFragment requestPermissionFragment = (RequestPermissionFragment) fragmentManager.findFragmentByTag(RequestPermissionFragment.class.getSimpleName());
        if (requestPermissionFragment == null) {
            requestPermissionFragment = new RequestPermissionFragment();
            fragmentManager.beginTransaction()
                    .add(requestPermissionFragment, RequestPermissionFragment.class.getSimpleName())
                    .commitAllowingStateLoss();
            fragmentManager.executePendingTransactions();
        }
        requestPermissionFragment.requestPermission(callBack, permissions);
    }

    /**
     * Author: JFangZ
     * Email: janezhang1901@163.com
     * Date:2020/12/16 10:25
     * Description:检查某个权限是否被允许
     *
     * @param context
     * @param permission 待检查的权限
     * @return true 表示该权限被允许,false 表示该权限被禁止
     */
    public static boolean isGranted(Context context, String permission) {
        return PermissionChecker.checkSelfPermission(context, permission) == PermissionChecker.PERMISSION_GRANTED;
    }

    /**
     * Author: JFangZ
     * Email: janezhang1901@163.com
     * Date:2021/1/12 18:31
     * Description:判断权限是否拒绝且不再询问
     *
     * @return true 为拒绝一次,false 为拒绝且不再询问
     */
    public static boolean isDeniedAndDoNotAskAgain(Activity activity, String permission) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            return activity.shouldShowRequestPermissionRationale(permission);
        }
        return false;
    }

    /**
     * Author: JFangZ
     * Email: janezhang1901@163.com
     * Date:2021/4/6 9:22
     * Description:申请权限,只申请一次,拒绝了就走失败回调
     */
    public static void requestOnce(FragmentActivity fragmentActivity, FragmentManager fragmentManager, OnRequestPermissionResultCallBack onRequestPermissionResultCallBack, String... permissions) {
        if (permissions == null || permissions.length == 0) {
            return;
        }
        // 拒绝且不再询问的权限的集合
        List<String> deniedAndDoNotAskAgainPermissionList = new ArrayList<>();
        // 待申请的权限的集合
        List<String> waitRequestPermissionList = new ArrayList<>();
        for (String permission : permissions) {
            // 如果该权限没有被允许,就不再去申请
            // 因为部分机型,申请某个权限时,即使该权限已经被允许过,还是会弹出权限申请对话框
            if (!isGranted(fragmentActivity, permission)) {
                waitRequestPermissionList.add(permission);
            }
        }
        if (waitRequestPermissionList.size() == 0) {
            if (onRequestPermissionResultCallBack != null) {
                onRequestPermissionResultCallBack.onSuccess();
            }
        } else {
            request(fragmentManager, new RequestPermissionFragment.CallBack() {
                @Override
                public void onSuccess() {
                    if (onRequestPermissionResultCallBack != null) {
                        onRequestPermissionResultCallBack.onSuccess();
                    }
                }

                @Override
                public void onFailure(List<String> deniedPermissionList) {
                    for (String deniedPermission : deniedPermissionList) {
                        // 如果该权限被拒绝且不再询问了,就不用再申请了,如果否则就是被拒绝一次的,再次申请
                        if (!isDeniedAndDoNotAskAgain(fragmentActivity, deniedPermission)) {
                            deniedAndDoNotAskAgainPermissionList.add(deniedPermission);
                        }
                    }
                    // 在被拒绝的权限列表中移除拒绝且不再询问的
                    deniedPermissionList.removeAll(deniedAndDoNotAskAgainPermissionList);
                    if (onRequestPermissionResultCallBack != null) {
                        onRequestPermissionResultCallBack.onFailure(deniedPermissionList, deniedAndDoNotAskAgainPermissionList);
                    }
                }
            }, waitRequestPermissionList.toArray(new String[]{}));
        }
    }

    /**
     * Author: JFangZ
     * Email: janezhang1901@163.com
     * Date:2021/4/6 9:22
     * Description:申请权限,直到被允许或被拒绝且不再询问,如果只是拒绝一次,就再次申请
     */
    public static void requestUntilSuccess(FragmentActivity fragmentActivity, FragmentManager fragmentManager, OnRequestPermissionResultCallBack onRequestPermissionResultCallBack, String... permissions) {
        if (permissions == null || permissions.length == 0) {
            return;
        }
        // 拒绝且不再询问的权限的集合
        List<String> deniedAndDoNotAskAgainPermissionList = new ArrayList<>();
        // 待申请的权限的集合
        List<String> waitRequestPermissionList = new ArrayList<>();
        for (String permission : permissions) {
            // 如果该权限没有被允许,就不再去申请
            // 因为部分机型,申请某个权限时,即使该权限已经被允许过,还是会弹出权限申请对话框
            if (!isGranted(fragmentActivity, permission)) {
                waitRequestPermissionList.add(permission);
            }
        }
        if (waitRequestPermissionList.size() == 0) {
            if (onRequestPermissionResultCallBack != null) {
                onRequestPermissionResultCallBack.onSuccess();
            }
        } else {
            request(fragmentManager, new RequestPermissionFragment.CallBack() {
                @Override
                public void onSuccess() {
                    if (onRequestPermissionResultCallBack != null) {
                        onRequestPermissionResultCallBack.onSuccess();
                    }
                }

                @Override
                public void onFailure(List<String> deniedPermissionList) {
                    for (String deniedPermission : deniedPermissionList) {
                        // 如果该权限被拒绝且不再询问了,就不用再申请了,如果否则就是被拒绝一次的,再次申请
                        if (!isDeniedAndDoNotAskAgain(fragmentActivity, deniedPermission)) {
                            deniedAndDoNotAskAgainPermissionList.add(deniedPermission);
                        }
                    }
                    // 在被拒绝的权限列表中移除拒绝且不再询问的
                    deniedPermissionList.removeAll(deniedAndDoNotAskAgainPermissionList);
                    if (deniedPermissionList.size() == 0) {
                        // 移除拒绝且不再询问的权限后,如果集合为空了,则说明全是被拒绝且不再询问的了
                        if (onRequestPermissionResultCallBack != null) {
                            onRequestPermissionResultCallBack.onFailure(new ArrayList<>(), deniedAndDoNotAskAgainPermissionList);
                        }
                    } else {
                        // 再次申请哪些只是拒绝一次,但还可以再次申请的
                        request(fragmentManager, this, deniedPermissionList.toArray(new String[]{}));
                    }
                }
            }, waitRequestPermissionList.toArray(new String[]{}));
        }
    }

    public static boolean isIgnoreBatteryOptimization(Context context) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
            return false;
        }
        PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
        if (powerManager != null) {
            return powerManager.isIgnoringBatteryOptimizations(AppUtil.getPackageName(context));
        }
        return false;
    }

    public static void requestIgnoreBatteryOptimization(Context context, FragmentManager fragmentManager, OnRequestPermissionResultCallBack onRequestPermissionResultCallBack) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
            return;
        }
        Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
        intent.setData(Uri.parse("package:" + AppUtil.getPackageName(context)));
        ActivityResultUtil.startActivityForResult(fragmentManager, intent, new OnActivityResultCallBack() {
            @Override
            public void onActivityResult(int requestCode, int resultCode, Intent data) {
                if (resultCode == Activity.RESULT_OK) {
                    if (onRequestPermissionResultCallBack != null) {
                        onRequestPermissionResultCallBack.onSuccess();
                    }
                } else {
                    if (onRequestPermissionResultCallBack != null) {
                        onRequestPermissionResultCallBack.onFailure(Arrays.asList(Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS), new ArrayList<>());
                    }
                }
            }
        });
    }
}